package com.abou.security.auth;

import java.util.Arrays;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import com.abou.manager.admin.ILoginManager;

/**
 * The authentication provider for the login process
 * 
 * @author khalid
 */
public class AbouAuthenticationProvider implements AuthenticationProvider {
  
  /**
   * The role for an authenticated user.
   */
  public static final String ADMIN_ROLE = "ROLE_ADMIN";
  
  @Autowired
  private ILoginManager loginManager;
  
  /**
   * @see org.springframework.security.authentication.AuthenticationProvider#authenticate(org.springframework.security.core.Authentication)
   */
  public Authentication authenticate(Authentication auth)
      throws AuthenticationException {

    boolean authenticated = false;
    
    if (!StringUtils.isBlank(auth.getName()) && auth.getCredentials() != null
        && auth.getPrincipal() instanceof String
        && auth.getCredentials() instanceof String) {
      
      // getting the login and password
      String login = auth.getName();
      String password = (String) auth.getCredentials();
      
      // authenticating the user
      authenticated = loginManager.authenticate(login, password);
    }
    
    Authentication newAuth = null;
    
    // creating the new authentication object
    if (authenticated) {
      
      // the user role can be used
      newAuth =
          new UsernamePasswordAuthenticationToken(
              auth.getPrincipal(), auth.getCredentials(),
              Arrays.asList((GrantedAuthority) new GrantedAuthorityImpl(
                  ADMIN_ROLE)));
      
    } else {
      
      // if the user cannot be authenticated, an exception is thrown
      throw new BadCredentialsException("Can't log user");
    }
    
    return newAuth;
  }
  
  /**
   * @see org.springframework.security.authentication.AuthenticationProvider#supports(java.lang.Class)
   */
  public boolean supports(Class<? extends Object> clazz) {

    return true;
  }
}
